# -*- coding: cp1252 -*-
from SimPy.Simulation import *
#
#  en este ejemplo se usaran dos recursos para simular dos puertas
#  de ingreso. Los carros hacen cola en esas puertas para otener
#  su ticket de parqueo. Por ello, cuando llega un carro puede
#  seleccionar la puerta que tiene la cola más corta

#  los atributos de un resource R:
#     R.waitQ  elementos que estan haciendo
#             cola para utilizar el recuros.
#     R.activeQ  elementos que estan siendo
#             atendidos por este recurso.


#se importan todas las librerias necesarios

from random import uniform
from random import Random, randint
import math 

from random import Random, randint


#se declara las calse que simula
class Banco(Process):
    #se define la variable sef, como quein contien e los datos propios de cada cliente
    def __init__(self,id):
        Process.__init__(self)
        self.id=id

    #se define este metodo, que sera el que realice las instrucciones de cambio, entre cada uno de los porcesos
    def procesoventanilla(self,tiempoespera,tiempotrans):
        yield hold,self,tiempoespera
        self.llega = now()
        # ahora decide que ventanilla usara para ingresar:
        # aquella que tenga menor número de carros en su cola

        #se define los terminos de la lista

        clientesxventanilla = [ len(ventanillas[0].waitQ) + len(ventanillas[0].activeQ),
                              len(ventanillas[1].waitQ) + len(ventanillas[1].activeQ),
                              len(ventanillas[2].waitQ) + len(ventanillas[2].activeQ),
                              len(ventanillas[3].waitQ) + len(ventanillas[3].activeQ)
                            ]
        
        for i in range(4): #hay 4 ventanillas
            #ve cual es la q tiene menos en su cola, o la q esta vasilla
            if clientesxventanilla[i] == 0 or clientesxventanilla[i] == min(clientesxventanilla):
                self.ventanilla = i  
                break
            
        print "el  ",self.id," hace cola en ventanilla ", self.ventanilla   #determina si le toca hacer cola en que ventnilla 
        yield request,self,ventanillas[self.ventanilla] #esperamos pasar por la ventanilla
        print "%5.1f %s toma ticket en ventanilla %d" %(self.llega,self.id, self.ventanilla)#le avisa q es su turno de pasar a una ventanilla indicada, y le asigna el itempo en q entra
        yield hold, self, tiempotrans       # nos tardamos un tiempo de transaccion en la ventanilla
        print "%5.1f %s pasa ventanilla %d" %(now(),self.id, self.ventanilla)
        tiempoTotal = now() - self.llega#el tiempo total seria el tiempo en el que sale, menos enn el que entra, ene ste tiempo incluye el tiempo q hizo cola
    
        
        
        print "%5.1f %s  tiempo total en el banco= %5.1f" %(now(),self.id,tiempoTotal)#se muestra su tempo total
        yield release, self, ventanillas[self.ventanilla]#el programa hace que deje la cola finalmente
        wt.observe(tiempoTotal) 

wt=Monitor()
initialize()
nrClientes=50 #numero de clientes
parkingLot=Resource(capacity=4,qType=FIFO)
#ahora definimos las dos ventanillas, como recursos. Las colocamos
#en una lista, por si en el futuro definimos más ventanillas.
ventanillas = [Resource(capacity=1,name="ventanilla1"), Resource(capacity=1,name="ventanilla2"), Resource(capacity=1,name="ventanilla3"),
               Resource(capacity=1,name="ventanilla4")] ##se crea la lista
#seed
r = Random(15555)#se crea la variable random, con su seed

for i in range(nrClientes): #se realiza el procesos mientras haya clientes
    c=Banco(id="cliente "+ str(i))
   
    #r2 = Random(14335)
    activate(c,c.procesoventanilla(tiempoespera=r.randint(1,480),tiempotrans=r.randint(1,30)))
simulate(until=1600)

#se imprime finalmente el promedia y la raiz cuadrada de la variaza(la desviacione standar)
print "Tiempo total en la U: \tmean = %5.1f, \n\t\tdesviacionest=%2d"%(wt.mean(), math.sqrt(wt.var()))

